package cn.edu.sdjzu.xg.eagle.util;
/** WT刷新令牌是一种特殊的令牌，用于在访问令牌（Access Token）过期后获取新的访问令牌，而无需重新进行身份验证。
 * 刷新令牌通常具有更长的过期时间，以便在访问令牌过期之前，可以使用刷新令牌来获取新的访问令牌。
 */


import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.DecodedJWT;

import java.util.Date;

public class JwtUtil {
    private static String secret;
    private static long expiration;
    private static long refreshExpiration;
    private static String issuer;
    private static String audience;

    static {
        // 从属性文件config.properties中读取JWT配置信息
        secret = ConfigUtil.getProperty("jwt.secret");
        expiration = Long.parseLong(ConfigUtil.getProperty("jwt.expiration"));
        refreshExpiration = Long.parseLong(ConfigUtil.getProperty("jwt.refresh.expiration"));
        issuer = ConfigUtil.getProperty("jwt.issuer");
        audience = ConfigUtil.getProperty("jwt.audience");
    }

    /**
     * 生成JWT
     * @return Builder对象，以方便调用者添加新的 claim
     */
    public static JWTCreator.Builder generateBuilder() {
        // 获取当前时间和过期时间
        Date now = new Date();
        Date expiryDate = new Date(now.getTime() + expiration * 1000);

        // 添加影响验证的标准信息
        JWTCreator.Builder builder = JWT.create()
                .withIssuer(issuer) // 设置JWT的签发者
                .withAudience(audience) // 设置JWT的受众
                .withIssuedAt(now) // 设置JWT的签发时间
                .withExpiresAt(expiryDate); // 设置JWT的过期时间
        return builder;
    }

    /**
     * 签名形成Token
     * @param builder
     * @return JWT字符串
     */
    public static String signToken(JWTCreator.Builder builder) {
        // 使用HMAC256算法和密钥对JWT进行签名，并返回生成的Token
        return builder.sign(Algorithm.HMAC256(secret));
    }

    /**
     * 刷新JWT
     *
     * @param token JWT字符串
     * @return 新的JWT字符串
     */
    public static String refreshToken(String token) {
        try {
            DecodedJWT decodedJWT = JWT.decode(token); // 解码JWT

            // 获取当前时间和刷新过期时间
            Date now = new Date();
            Date refreshExpiryDate = new Date(now.getTime() + refreshExpiration * 1000);

            return JWT.create()
                    .withIssuer(decodedJWT.getIssuer()) // 设置JWT的签发者
                    .withAudience(decodedJWT.getAudience().get(0)) // 设置JWT的受众
                    .withIssuedAt(now) // 设置JWT的签发时间
                    .withExpiresAt(refreshExpiryDate) // 设置JWT的刷新过期时间
                    // 设置其他的JWT声明
                    .sign(Algorithm.HMAC256(secret)); // 使用HMAC256算法和密钥对JWT进行签名
        } catch (JWTVerificationException e) {
            // 解码或验证失败
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 验证JWT
     *
     * @param token JWT字符串
     * @return 验证结果，true表示验证通过，false表示验证失败
     */
    public static boolean validateToken(String token) {
        try {
            JWTVerifier verifier = JWT.require(Algorithm.HMAC256(secret)) // 使用HMAC256算法和密钥验证签名
                    .withIssuer(issuer) // 设置JWT的签发者
                    .withAudience(audience) // 设置JWT的受众
                    .build();

            DecodedJWT decodedJWT = verifier.verify(token); // 验证JWT的签名

            // 验证过期时间
            Date expirationDate = decodedJWT.getExpiresAt(); // 获取JWT的过期时间
            Date now = new Date(); // 当前时间
            if (expirationDate != null && expirationDate.before(now)) {
                return false; // 过期时间已过期，返回false
            }
            return true; // 验证通过
        } catch (JWTVerificationException e) {
            e.printStackTrace();
            return false; // 验证失败，返回false
        }
    }
}